home *** CD-ROM | disk | FTP | other *** search
/ Amiga Games 1996 July / Amiga Games 1996 #7.iso / archive / userbox / publicdomain / hildu.lha / HiL-Du / du.c < prev    next >
C/C++ Source or Header  |  1996-03-27  |  10KB  |  342 lines

  1.  
  2. #include "du_h.h"
  3.  
  4. struct ExecBase *SysBase;
  5. struct DosLibrary *DOSBase = NULL;
  6. struct Library *UtilityBase = NULL;
  7.  
  8. STRPTR verstag = "$VER: du 1.1 (96.3.17)\r\n";
  9.  
  10. struct entry
  11.    {
  12.    struct Node node;
  13.    struct InfoData info;
  14.    BOOL showit;
  15.    UBYTE name[32];
  16.    };
  17.  
  18. #define ENTRY_VOLUME NT_USER-1
  19. #define ENTRY_DEVICE NT_USER-2
  20. #define ENTRY_ASSIGN NT_USER-3
  21. #define ENTRY_DEVDISK NT_USER-8
  22.  
  23. VOID btocstr(BSTR, STRPTR, UWORD);
  24. VOID killlist(struct List *);
  25. STRPTR itok(ULONG num, STRPTR buf);
  26. LONG __asm cmpfunc(register __a1 struct entry *, register __a2 struct entry *);
  27.  
  28. struct Hook cmphook =
  29.    {
  30.    {NULL, NULL},
  31.    (ULONG (*)())cmpfunc,
  32.    NULL, NULL
  33.    };
  34.  
  35. LONG __saveds start(VOID)
  36.    {
  37.    LONG rc = 0;
  38.  
  39.    SysBase = *(struct ExecBase **)4L;
  40.    if ((DOSBase = (struct DosLibrary *)OpenLibrary("dos.library", 37)) &&
  41.     (UtilityBase = OpenLibrary("utility.library", 37)))
  42.       {
  43.       struct RDArgs *rdargs;
  44.       STRPTR *devs = NULL, *devpt;
  45.       struct Process *proc;
  46.       APTR win;
  47.       struct List dlist;
  48.       struct DosList *dl, *vn;
  49.       struct entry *de, **array;
  50.       struct InfoData *info;
  51.       UWORD i, count;
  52.  
  53.       ULONG size, used, free;
  54.       UBYTE sizebuf[6], usedbuf[6], freebuf[6], buf[64];
  55.       BOOL moreinfo;
  56.       STRPTR disktype, status;
  57.       UBYTE matchbuf[256];
  58.  
  59.       if (rdargs = ReadArgs("Devices/M", (LONG *)&devs, NULL))
  60.          {
  61.          proc = (struct Process *)FindTask(NULL);
  62.          win = proc->pr_WindowPtr;
  63.          proc->pr_WindowPtr = (APTR)-1; // suppress system requesters
  64.  
  65.          dlist.lh_Head = (struct Node *)&dlist.lh_Tail;
  66.          dlist.lh_Tail = NULL;
  67.          dlist.lh_TailPred = (struct Node *)&dlist;
  68.  
  69.          if (info = AllocMem(sizeof(struct InfoData), MEMF_PUBLIC))
  70.             {
  71.             dl = LockDosList(LDF_DEVICES|LDF_READ);
  72.             i = 0;
  73.             while (dl = NextDosEntry(dl, LDF_DEVICES|LDF_READ))
  74.                {
  75.                if (dl->dol_Task && DoPkt(dl->dol_Task,
  76.                 ACTION_DISK_INFO, MKBADDR(info), NULL, NULL, NULL, NULL))
  77.                   {
  78.                   if (de = AllocMem(sizeof(struct entry), MEMF_CLEAR))
  79.                      {
  80.                      de->node.ln_Pri = 1;
  81.                      de->node.ln_Type = ENTRY_DEVICE;
  82.                      de->node.ln_Name = de->name;
  83.                      de->info = *info;
  84.                      btocstr(dl->dol_Name, de->name, 28);
  85.                      strcat(de->name, ":");
  86.                      Enqueue(&dlist, (struct Node *)de);
  87.                      i++;
  88.                      }
  89.                   }
  90.                }
  91.             UnLockDosList(LDF_DEVICES|LDF_READ);
  92.             FreeMem(info, sizeof(struct InfoData));
  93.             }
  94.  
  95.          count = i;
  96.          if (array = AllocMem(sizeof(APTR)*count, MEMF_ANY))
  97.             {
  98.             for (i = 0, de = (struct entry *)dlist.lh_Head;
  99.              de->node.ln_Succ;
  100.              i++, de = (struct entry *)de->node.ln_Succ)
  101.                array[i] = de;
  102.  
  103.             QSort((APTR)array, count, &cmphook);
  104.  
  105.             for (devpt = devs; *devpt; devpt++)
  106.                {
  107.                ParsePatternNoCase(*devpt, matchbuf, 254);
  108.                for (i = 0; i < count; i++)
  109.                   {
  110.                   de = array[i];
  111.                   de->showit |= MatchPatternNoCase(matchbuf, de->node.ln_Name);
  112.                   }
  113.                }
  114.  
  115.             PutStr("Unit     Size Block DiskType  Used Free Full  Errs   Status    Volume\n");
  116.    /***
  117.     ***             Unit     Size Block DiskType  Used Free Full  Errs   Status    Volume
  118.     ***             ¯¯¯¯¯¯¯¯ ¯¯¯¯ ¯¯¯¯¯ ¯¯¯¯¯¯¯¯  ¯¯¯¯ ¯¯¯¯ ¯¯¯¯  ¯¯¯¯ ¯¯¯¯¯¯¯¯¯¯  ¯¯¯¯¯¯¯¯
  119.     ***/
  120.             for (i = 0; i < count; i++)
  121.                {
  122.                de = array[i];
  123.                if (devs && !de->showit)
  124.                   continue;
  125.  
  126.                moreinfo = TRUE;
  127.                switch(de->info.id_DiskType)
  128.                   {
  129.                   case ID_NO_DISK_PRESENT:
  130.                      disktype = "No disk present";
  131.                      moreinfo = FALSE;
  132.                      break;
  133.  
  134.                   case ID_UNREADABLE_DISK:
  135.                      disktype = "Unreadable disk";
  136.                      moreinfo = FALSE;
  137.                      break;
  138.  
  139.                   case ID_NOT_REALLY_DOS:
  140.                      disktype = "Not a DOS disk";
  141.                      moreinfo = FALSE;
  142.                      break;
  143.  
  144.                   case ID_KICKSTART_DISK:
  145.                      disktype = "Kickstart disk";
  146.                      moreinfo = FALSE;
  147.                      break;
  148.  
  149.                   case ID_DOS_DISK:
  150.                      disktype = "   OFS  ";
  151.                      break;
  152.  
  153.                   case ID_FFS_DISK:
  154.                      disktype = "   FFS  ";
  155.                      break;
  156.  
  157.                   case ID_INTER_DOS_DISK:
  158.                      disktype = "INTL/OFS";
  159.                      break;
  160.  
  161.                   case ID_INTER_FFS_DISK:
  162.                      disktype = "INTL/FFS";
  163.                      break;
  164.  
  165.                   case ID_FASTDIR_DOS_DISK:
  166.                      disktype = " DC/OFS ";
  167.                      break;
  168.  
  169.                   case ID_FASTDIR_FFS_DISK:
  170.                      disktype = " DC/FFS ";
  171.                      break;
  172.  
  173.                   case ID_MSDOS_DISK:
  174.                      disktype = " MS-DOS ";
  175.                      break;
  176.  
  177.                   default:
  178.                      {
  179.                      UWORD j;
  180.                      UBYTE c;
  181.                      STRPTR s;
  182.  
  183.                      strcpy(buf, "Unreadable disk (\'");
  184.                      s = buf+strlen("Unreadable disk (\'");
  185.                      for (j = 0; j < 4; j++)
  186.                         {
  187.                         c = (de->info.id_DiskType >> ((3-i)*8)) & 0xFF;
  188.                         if (c & 0x60)
  189.                            *s++ = c;
  190.                         else if (c<10)
  191.                            {
  192.                            *s++ = '\\';
  193.                            *s++ = c+'0';
  194.                            }
  195.                         else
  196.                            *s++ = '?';
  197.                         }
  198.                      *s = '\0';
  199.                      strcat(buf, "\')");
  200.                      disktype = buf;
  201.                      moreinfo = FALSE;
  202.                      }
  203.                   }
  204.  
  205.                if (moreinfo)
  206.                   {
  207.                   size = de->info.id_NumBlocks*de->info.id_BytesPerBlock;
  208.                   used = de->info.id_NumBlocksUsed*de->info.id_BytesPerBlock;
  209.                   free = size-used;
  210.  
  211.                   if (vn = (struct DosList *)BADDR(de->info.id_VolumeNode))
  212.                      btocstr(vn->dol_Name, buf, 60);
  213.                   else
  214.                      buf[0] = '\0';
  215.  
  216.                   switch(de->info.id_DiskState)
  217.                      {
  218.                      case ID_WRITE_PROTECTED:
  219.                         status = "Read Only ";
  220.                         break;
  221.  
  222.                      case ID_VALIDATED:
  223.                         status = "Read/Write";
  224.                         break;
  225.  
  226.                      case ID_VALIDATING:
  227.                         status = "Validating";
  228.                         break;
  229.  
  230.                      default:
  231.                         status = " Unknown  ";
  232.                      }
  233.  
  234.                   Printf("%-8s %4s %5ld %s  %4s %4s %3ld%%  %3ld  %s  %s\n",
  235.                    de->node.ln_Name,
  236.                    itok(size, sizebuf),
  237.                    de->info.id_BytesPerBlock,
  238.                    disktype,
  239.                    itok(used, usedbuf),
  240.                    itok(free, freebuf),
  241.                    (de->info.id_NumBlocksUsed*200+1)/de->info.id_NumBlocks/2,
  242.                    de->info.id_NumSoftErrors,
  243.                    status, buf);
  244.                   }
  245.                else
  246.                   Printf("%-8s    %s\n", de->node.ln_Name, disktype);
  247.                if (SetSignal(0L, SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D) &
  248.                 (SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D))
  249.                   {
  250.                   PrintFault(ERROR_BREAK, NULL);
  251.                   rc = 20;
  252.                   break;
  253.                   }
  254.                }
  255.             FreeMem(array, sizeof(APTR)*count);
  256.             }
  257.          FreeArgs(rdargs);
  258.          }
  259.       else
  260.          PrintFault(IoErr(), NULL);
  261.  
  262.       killlist(&dlist);
  263.  
  264.       proc->pr_WindowPtr = win;
  265.       }
  266.    CloseLibrary((struct Library *)DOSBase);
  267.    CloseLibrary(UtilityBase);
  268.  
  269.    return rc;
  270.    }
  271.  
  272. VOID btocstr(BSTR src, STRPTR dest, UWORD maxlen)
  273.    {
  274.    UWORD i;
  275.    STRPTR s;
  276.  
  277.    s = BADDR(src);
  278.    i = *s++;
  279.    if (i>maxlen)
  280.       i = maxlen;
  281.    while (i--)
  282.       *dest++ = *s++;
  283.    *dest = '\0';
  284.    }
  285.  
  286.  
  287. VOID killlist(struct List *list)
  288.    {
  289.    struct entry *de;
  290.  
  291.    while (de = (struct entry *)RemTail(list))
  292.       {
  293.       FreeMem(de, sizeof(struct entry));
  294.       }
  295.    }
  296.  
  297. STRPTR itok(ULONG num, STRPTR buf)
  298.    {
  299.    UBYTE *exp = " KMG";
  300.    ULONG m = 1, m2, res, mod;
  301.  
  302.    if (num<1024)
  303.       {
  304.       sprintf(buf, "%ld", num);
  305.       return buf;
  306.       }
  307.    while ((res = (num+m/2)/m) >= 1000)
  308.       {
  309.       m2 = m;
  310.       m *= 1024;
  311.       exp++;
  312.       }
  313.    if (res < 11)
  314.       {
  315.       res = num/m;
  316.       if (res < 1)
  317.          {
  318.          sprintf(buf, "1.0%lc", *exp);
  319.          return buf;
  320.          }
  321.       mod = ((num/m2)%1024*10+512)/1024;
  322.       if (mod > 9)
  323.          {
  324.          res++;
  325.          mod = 0;
  326.          }
  327.       if (res < 10)
  328.          {
  329.          sprintf(buf, "%ld.%ld%lc", res, mod, *exp);
  330.          return buf;
  331.          }
  332.       }
  333.    sprintf(buf, "%ld%lc", res, *exp);
  334.  
  335.    return buf;
  336.    }
  337.  
  338. LONG __asm cmpfunc(register __a1 struct entry *e1, register __a2 struct entry *e2)
  339.    {
  340.    return Stricmp(e1->node.ln_Name, e2->node.ln_Name);
  341.    }
  342.